#include "aerial\Scout.h"

#include "hge\hgevector.h"

float friction = 0.8;

Scout::Scout(hgeResourceManager* hgeResMan, HGE* hge,
	float _x, float _y)
	: IObject(hgeResMan, hge)
{
	x = _x;
	y = _y;
	speed = 0;
	dx = dy = 0;
	rot = 0;
	rotDelta = 0;
	
	boostTimeLimit = 5.0f;
	boostRate = 3.0f;
	boostTimer = 0;
	boostState = Normal;

	mirageTimeLimit = 5.0f;
	mirageTimer = 0;
	isMirage = false;

	speed = 0;
	speedLimit = 1.0f;

	body = new hgeSprite(hgeResMan->GetTexture("tex.scout"),
		0, 0, 506.0f, 544.0f);
	body->SetHotSpot(253.0f, 272.0f);
}
Scout::~Scout()
{
	delete body;
}

void Scout::render()
{
	body->RenderEx(x, y, rot, 0.2f, 0.2f);
	if (boostState == Boosting)
		;					// TODO: draw effect here
	else if (boostState == Cooling)
		;
}
bool Scout::update(float dt)
{
	// Flying
	if (flyState == StartFly)
	{
		speed += 5 * dt;
		if (speed > speedLimit)
			flyState = Flying;
	}
	else if (flyState == StopFly)
	{
		speed -= 5 * dt;
		if (speed <= 0)
		{
			speed = 0;
			flyState = Stopped;
		}
	}
	// TODO: eliminate cos/sin
	x += speed * cos(rot - M_PI / 2);
	y += speed * sin(rot - M_PI / 2);

	// Boosting
	if (boostState == Boosting)
	{
		boostTimer += dt;
		if (boostTimer > boostTimeLimit)
			boostOff();
	}
	else if (boostState == Cooling)
	{
		boostTimer -= dt;
		if (boostTimer < 0)
			boostState = Normal;
	}

	// Mirage
	// TODO: animation

	// Rotating
	float drot = abs(dt * rotDelta * 10);
	if (rotDelta >= 0 && rotCW)
	{
		rot += drot;
		rotDelta -= drot;
	}
	else if (rotDelta < 0 && !rotCW)
	{
		rot -= drot;
		rotDelta += drot;
	}
	if (rot <= -M_PI)
		rot += M_PI * 2;
	else if (rot > M_PI)
		rot -= M_PI * 2;

	return false;
}

void Scout::boostOn()
{
	if (boostState == Boosting)
		return;
	speed *= boostRate;
	boostState = Boosting;
}
void Scout::boostOff()
{
	if (boostState != Boosting)
		return;
	boostState = Cooling;
	boostTimer = boostTimer;			// cool time = boosted time
	speed /= boostRate;
}
void Scout::mirageOn()
{
	// TODO: More invisible on other player's screen.
	if (isMirage)
		return;
	isMirage = true;
	body->SetColor(0x22FFFFFF);
}
void Scout::mirageOff()
{
	if (!isMirage)
		return;
	isMirage = false;
	body->SetColor(0xFFFFFFFF);
}

void Scout::headTo(int _x, int _y)
{
	hgeVector a(_x - x, _y - y);
	hgeVector n(0, -1);
	rotDelta = (_x - x < 0 ? -a.Angle(&n) : a.Angle(&n)) - rot;
	if (rotDelta > M_PI)
		rotDelta = rotDelta - 2 * M_PI;
	else if (rotDelta < -M_PI)
		rotDelta = 2 * M_PI + rotDelta;
	rotCW = rotDelta >= 0;
}
void Scout::fly(int _x, int _y)
{
	hgeVector a(_x - x, _y - y);
	a.Normalize();
	headTo(_x, _y);
	if (flyState == StartFly || flyState == Flying)
		return;
	flyState = StartFly;
}
void Scout::flyOff()
{
	flyState = StopFly;
}